package service

import (
	"fmt"
	beego "github.com/beego/beego/v2/server/web"
	"ksd-social-api/commons/base/service"
	"ksd-social-api/commons/page"
	"ksd-social-api/modules/note/model"
	"ksd-social-api/modules/note/model/context"
	"ksd-social-api/modules/note/model/vo"
	"ksd-social-api/utils"
	"ksd-social-api/utils/rdb"
	"math"
)

type NoteCommentService struct {
	service.BaseService
}

/**
 * 根据用户id,小册id和用户id
 * 目的就是：用户自己的评论只能自己删除，别人不允许
 * @author feige
 * @date 2023-11-21
 * @version 1.0
 * @desc
 */
func (service *NoteCommentService) DelCommentByIdAndUserId(ctx context.CommentDelContext) bool {
	return commentMapper.DelCommentById(ctx.Id.Uint64(), ctx.Opid.Uint64(), ctx.UserId, ctx.SystemId)
}

/**
 * 保存小册评论
 * @author feige
 * @date 2023-11-20
 * @version 1.0
 * @desc
 */
func (service *NoteCommentService) SaveComment(context context.NoteCommentContext) bool {
	// 把context的数据拷贝到数据模型中
	var comment model.NoteComment
	utils.CopyProperties(&comment, context)
	comment.Id = context.Id
	comment.Opid = context.Opid.Uint64()
	comment.Status = 1
	// 然后开始调用执行保存
	saveFlag := commentMapper.SaveComment(&comment)
	if saveFlag {
		return true
	}
	return false
}

/**
 * 根据小册ID查询评论信息
 * @author feige
 * @date 2023-11-20
 * @version 1.0
 * @desc
 */
func (service *NoteCommentService) FindCommentAndPage(ctx context.CommentPageContext) *page.Page {
	commentPage, _ := commentMapper.FindCommentPage(ctx)
	commentList := commentPage.Records.([]model.NoteComment)
	if commentList != nil {
		noteCommentVos := []vo.CommentVo{}
		for _, comment := range commentList {
			commentVo := vo.CommentVo{}
			utils.CopyProperties(&commentVo, comment)

			commentVo.Children = []*vo.CommentVo{}
			commentVo.PageNo = 0

			floor := math.Floor(float64(commentVo.ReplyNum / 3))
			modNum := commentVo.ReplyNum % 3
			if modNum == 0 {
				commentVo.Pages = int64(floor)
			} else {
				commentVo.Pages = int64(floor) + 1
			}

			noteCommentVos = append(noteCommentVos, commentVo)
		}
		commentPage.Records = noteCommentVos
	}

	return commentPage
}

/**
 * 评论的频率检查
 * @author feige
 * @date 2023-11-21
 * @version 1.0
 * @desc
 */
func (service *NoteCommentService) CheckLimitComment(userId uint64, systemId uint64) any {
	// 时间频率限制 commentIntervalSeconds == -1不限制，否则就会限制
	// 5代表用户在5秒之内只能评论一次，如果超过在5秒之内提交N次就不停的提示：操作繁忙
	commentIntervalSeconds := beego.AppConfig.DefaultInt("comment.limit.seconds", 60)
	if commentIntervalSeconds > 0 {
		result := service.GetCommentInterval(userId, systemId, commentIntervalSeconds)
		if !result {
			return "操作过于频繁，请稍后再试"
		}
	}

	// 每日用户最大的评论次数 commentEveryDayLimit==-1 代表不限制，否则就会限制
	commentEveryDayLimit := beego.AppConfig.DefaultInt("comment.limit.everyday", 20)
	if commentEveryDayLimit > 0 {
		getCommentCountEveryDay := service.GetCommentEveryDay(userId, systemId)
		if getCommentCountEveryDay > commentEveryDayLimit {
			return "今日评论次数超过限制"
		}
	}

	return nil
}

/**
 * 这里就获取每次评论都进行计数
 * @author feige
 * @date 2023-11-21
 * @version 1.0
 * @desc
 */
func (service *NoteCommentService) GetCommentEveryDay(userId uint64, systemId uint64) int {
	// 准备一个用户评论的计数key
	key := fmt.Sprintf("note:comment:count:%s:%d", userId, systemId)
	// 开始执行计数器
	count, _ := rdb.RdbIncr(key)
	// 如果count == 1
	if count == 1 {
		rdb.RdbExKey(key, 60*60*24)
	}
	// 返回具体计算器
	return count
}

/**
 * 这里就是setnxex的代码
 * @author feige
 * @date 2023-11-21
 * @version 1.0
 * @desc
 */
func (service *NoteCommentService) GetCommentInterval(userId uint64, systemId uint64, intervalTime int) bool {
	key := fmt.Sprintf("note:comment:interval:%s:%d", userId, systemId)
	result := rdb.RdbSetEXNX(key, userId, intervalTime)
	return result
}
